package tv.geir.slackspace.interceptor;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.BeforeAdvice;
import org.springframework.aop.MethodBeforeAdvice;

import tv.geir.slackspace.monitor.PerformanceMonitor;
import tv.geir.slackspace.monitor.PerformanceMonitor.MonitorKey;

public class PerformanceMonitorInterceptor implements MethodBeforeAdvice, AfterReturningAdvice {

	private int level;
	
	PerformanceMonitor monitor =  PerformanceMonitor.getMonitor();

	private ThreadLocal<MonitorKey> key = new ThreadLocal<MonitorKey>();;
	
	private Map<String, Boolean> methods;


	
	/**
	 * Set the methods (method name only) that should be monitored
	 * @param methodSet
	 */
	public void setMethods(Set<String> methodSet) {
		methods = new HashMap<String, Boolean>();
		for( String m : methodSet ) {
			methods.put(m, Boolean.TRUE);
		}
	}



	public int getLevel() {
		return level;
	}



	public void setLevel(int level) {
		this.level = level;
	}



	public void before(Method method, Object[] arg1, Object obj)
			throws Throwable {
		if( methods.get(method.getName()) == null ) {
			return;
		}
		MonitorKey k = monitor.startMonitoring(level, obj.getClass().getName() + "." + method.getName() + "()" );		
		key.set( k );
		
	}



	public void afterReturning(Object arg0, Method method, Object[] arg2,
			Object arg3) throws Throwable {
		if( methods.get(method.getName()) == null ) {
			return;
		}
		MonitorKey k = key.get();
		monitor.stopMonitoring(k);
	}

}
